package dt.inlee.common.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;

import dt.inlee.common.dao.ifc.IGenericHibernateDao;
import dt.inlee.common.pagination.ConditionBean;
import dt.inlee.common.pagination.ConditionType;
import dt.inlee.common.pagination.CriteriaUtil;
import dt.inlee.common.pagination.PageBean;
import dt.inlee.common.pagination.SearchBean;
import dt.inlee.common.util.BaseUtil;

/**
 * Hibernate 操作模板实现类 <br>
 * <br>
 * 
 * @param <实体类型>
 * @param <主键类型>
 */
@SuppressWarnings({"unchecked","deprecation"})
public class GenericHibernateDao<T, ID extends Serializable> extends HibernateDaoSupport
        implements
            IGenericHibernateDao<T, ID> {

    @Override
    public boolean executBySql(String sql) {
        Session se = this.getSessionFactory().openSession();
        java.sql.Connection conn = null;
        PreparedStatement pstmt = null;
        boolean flag = false;
        try {
            conn = se.connection();
            pstmt = conn.prepareStatement(sql);

            flag = pstmt.execute();
            return flag;
        } catch (Exception e) {
            System.out.println("error:" + e.getMessage());
            return flag;
        } finally {
            try {
                pstmt.close();
                conn.close();
                releaseSession(se);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public List<T> FindBySQL(String sql) {
        List<T> list = this.getSession().createSQLQuery(sql).list();
        releaseSession(this.getSession());
        return list;
    }

    public T findClassBSQL(String sql) {
        T t = (T) this.getSession().createSQLQuery(sql);
        releaseSession(this.getSession());
        return t;
    }

    public void SessionFlush() {
        this.getSession().flush();
    }

    /**
     * 
     * @param sql sql语句
     * @param params 参数列表
     * @return 集合List
     */
    public List<T> FindBySQL(String sql, Object[] params) {
        Query query = this.getSession().createSQLQuery(sql);
        if (params != null && params.length > 0) {
            for (int i = 0; i < params.length; i++) {
                System.out.println(params[i]);
                query.setParameter(i, params[i]);
            }
        }
        List<T> list = query.list();
        releaseSession(this.getSession());
        return list;
    }

    public int countSql(String sql) {

        int count = 0;
        PreparedStatement pStmt = null;
        ResultSet rs = null;
        Connection conn = null;
        Session session = this.getSession();
        try {
            conn = session.connection();
            pStmt = conn.prepareStatement(sql);
            rs = pStmt.executeQuery();
            if (rs.next()) {
                count = rs.getInt(1);
                releaseSession(this.getSession());
            }
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
        return count;
    }

    public int countBySQL(String sql) {
        int result = 0;
        Session se = this.getSessionFactory().openSession();
        java.sql.Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = se.connection();
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                result = rs.getInt(1);
            }
            rs.close();
        } catch (Exception e) {
            System.out.println("error:" + e.getMessage());
        } finally {
            try {
                pstmt.close();
                conn.close();
                releaseSession(se);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public double sumBySQL(String sql) {
        double result = 0.0;
        Session se = this.getSessionFactory().openSession();
        java.sql.Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = se.connection();
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            rs.next();
            if (rs.getRow() > 0) {
                result = rs.getDouble(1);
            }
            rs.close();
        } catch (Exception e) {
            System.out.println("error:" + e.getMessage());
        } finally {
            try {
                pstmt.close();
                conn.close();
                releaseSession(se);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public boolean execBySQL(String sql) {
        Session se = this.getSessionFactory().openSession();
        java.sql.Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = se.connection();
            pstmt = conn.prepareStatement(sql);

            rs = pstmt.executeQuery();
            rs.close();
        } catch (Exception e) {
            System.out.println("error:" + e.getMessage());
            return false;
        } finally {
            try {
                pstmt.close();
                conn.close();
                releaseSession(se);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    public Object exeSQL(String sql) {
        System.out.println(sql);
        Session se = this.getSessionFactory().openSession();
        java.sql.Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        Object obj = null;
        try {
            conn = se.connection();

            pstmt = conn.prepareStatement(sql);

            rs = pstmt.executeQuery();
            if (rs.next()) {
                obj = rs.getObject(1);
            }
            rs.close();
        } catch (Exception e) {
            System.out.println("error:" + e.getMessage());
            return null;
        } finally {
            try {
                pstmt.close();
                conn.close();
                releaseSession(se);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return obj;
    }

    public int exeMoreSql(String sql) {

        int count = 0;
        PreparedStatement pStmt = null;
        ResultSet rs = null;
        Connection conn = null;
        Session session = this.getSession();
        try {
            conn = session.connection();
            pStmt = conn.prepareStatement(sql);
            rs = pStmt.executeQuery();
            if (rs.next()) {
                count = rs.getInt(1);
                releaseSession(this.getSession());
            }
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
        return count;

    }

    public void queryBySQL(String sql, List<String> titles, List<Object[]> queryData) {
        Session se = this.getSessionFactory().openSession();
        java.sql.Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = se.connection();

            pstmt = conn.prepareStatement(sql);

            rs = pstmt.executeQuery();

            ResultSetMetaData rsmd = rs.getMetaData();

            int count = rsmd.getColumnCount();
            if (titles != null) {

                for (int i = 0; i < count; i++) {
                    titles.add(rsmd.getColumnName(i + 1));
                }
            }
            while (rs.next()) {
                Object[] lines = new Object[count];
                for (int i = 0; i < count; i++) {
                    lines[i] = rs.getObject(i + 1);
                }
                queryData.add(lines);
            }
            rs.close();
        } catch (Exception e) {
            System.out.println("error:" + e.getMessage());
            System.out.println("sql:" + sql);
        } finally {
            try {
                pstmt.close();
                conn.close();
                releaseSession(se);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 实体类型
     */
    private Class<T> entityClass;

    /**
     * 获取实体类
     * 
     * @return
     */
    public Class<T> getEntityClass() {
        if (entityClass == null) {
            entityClass =
                    (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        }
        return entityClass;
    }

    /**
     * 设置实体类
     * 
     * @param entityClass
     */
    public void setEntityClass(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    /**
     * 是否包含该实体信息
     * 
     * @param 实体对象
     * @return TRUE: 包含 FALSE:不包含
     * @throws DataAccessException
     */
    public boolean contains(T t) {
        return this.getHibernateTemplate().contains(t);
    }

    /**
     * 根据复合条件查询数据量
     * 
     * @param 条件和排序查询对象
     * @return 数据量
     * @throws EXCEPTION
     */
    public int count(SearchBean params) {
        int count = 0;

        Session session = this.getSession();

        Criteria criteria = null;

        DetachedCriteria detachedCriteria = null;

        if (params == null) {
            params = new SearchBean();
        }

        detachedCriteria = params.getDetachedCriteria();

        if (detachedCriteria != null) {
            criteria = detachedCriteria.getExecutableCriteria(session);
        } else {
            criteria = session.createCriteria(getEntityClass());

            CriteriaUtil.processParams(criteria, params.getConditions());

            count = (Integer) criteria.setProjection(Projections.rowCount()).uniqueResult();

            criteria.setProjection(null);

        }
        releaseSession(session);
        return count;
    }

    /**
     * 根据ID删除实体对象
     * 
     * @param ID
     * @throws EXCEPTION
     */
    @Transactional
    public void delete(ID id) {
        T t = this.get(id);
        this.delete(t);
    }

    /**
     * 根据ID删除实体对象并加锁
     * 
     * @param ID
     * @param 锁模式
     * @throws EXCEPTION
     */
    public void delete(ID id, LockMode lockMode) {
        T t = this.get(id);
        this.delete(t, lockMode);
    }

    /**
     * 删除实体对象
     * 
     * @param 实体对象
     * @throws EXCEPTION
     */
    @Transactional
    public void delete(T t) {
        this.getHibernateTemplate().delete(t);
    }

    /**
     * 删除实体对象并加锁
     * 
     * @param 实体对象
     * @param 锁类型
     * @throws EXCEPTION
     */
    public void delete(T t, LockMode lockMode) {
        this.getHibernateTemplate().delete(t, lockMode);
    }

    /**
     * 删除实体对象集合
     * 
     * @param 实体对象集合
     * @throws EXCEPTION
     */
    public void deleteAll(Collection<T> entities) {
        this.getHibernateTemplate().deleteAll(entities);
    }

    /**
     * 根据ID集合删除实体对象集合
     * 
     * @param 主键字段
     * @param ID数组
     * @throws EXCEPTION
     */
    public void deleteAll(String field, ID[] ids) {
        SearchBean params = new SearchBean();
        params.addCondition(new ConditionBean(field, ConditionType.IN, ids));
        List<T> lst = this.find(params);
        this.deleteAll(lst);
    }

    /**
     * 使用条件和排序查询对象检索数据
     * 
     * @param 条件和排序查询对象
     * @return 实体对象集合
     * 
     */
    public List<T> find(SearchBean params) {

        Session session = this.getSession();

        DetachedCriteria detachedCriteria = null;

        Criteria criteria = null;

        if (params == null) {
            params = new SearchBean();
        }

        // 离线查询对象
        detachedCriteria = params.getDetachedCriteria();

        // 如果离线查询对象为非空，则使用离线查询
        if (detachedCriteria != null) {
            // 将离线查询对象绑定到当前Session
            criteria = detachedCriteria.getExecutableCriteria(session);
        } else {
            criteria = session.createCriteria(getEntityClass());

            CriteriaUtil.processParams(criteria, params.getConditions());

            CriteriaUtil.processOrders(criteria, params.getOrders());

            criteria.setCacheable(params.isCacheAble());

            if (params.isCacheAble()) {
                criteria.setCacheMode(params.getCacheMode());
            }

            if (params.getCacheRegion() != null) {
                criteria.setCacheRegion(params.getCacheRegion());
            }

            // 设置锁模式
            criteria.setLockMode(params.getLockMode());
            // 设置刷新模式
            criteria.setFlushMode(params.getFlushMode());
            // 设置总数据
        }

        // 设置查询结果
        List<T> lstResult = criteria.list();
        releaseSession(session);
        return lstResult;
    }

    /**
     * 使用HQL语句检索数据
     * 
     * @param HQL语句
     * @return 实体对象集合
     * @throws EXCEPTION
     */
    public List<T> find(String queryString) {
        List<T> lst = this.getHibernateTemplate().find(queryString);
        return lst;
    }

    /**
     * 使用带单个参数的HQL语句检索数据
     * 
     * @param HQL语句
     * @param 参数值
     * @return 实体对象集合
     * @throws EXCEPTION
     */
    public List<T> find(String queryString, Object value) {
        List<T> lst = this.getHibernateTemplate().find(queryString, value);
        return lst;
    }

    /**
     * 使用带多个参数的HQL语句检索数据
     * 
     * @param HQL语句
     * @param 参数值数组
     * @return 实体对象集合
     * @throws EXCEPTION
     */
    public List<T> find(String queryString, Object[] values) {
        List<T> lst = this.getHibernateTemplate().find(queryString, values);
        return lst;
    }

    public List<?> findColumn(String queryString, Object value) {
        List<?> list = this.getHibernateTemplate().find(queryString, value);
        return list;
    }

    public List<?> findColumn(String queryString) {
        List<?> list = this.getHibernateTemplate().find(queryString);
        return list;
    }

    /**
     * 使用命名的HQL语句检索数据
     * 
     * @param 命名的HQL语句
     * @return 实体对象集合
     * @throws EXCEPTION
     */
    public List<T> findByNamedQuery(String queryName) {
        List<T> lst = this.getHibernateTemplate().findByNamedQuery(queryName);
        return lst;
    }

    /**
     * 使用单个参数的命名HQL语句检索数据
     * 
     * @param 命名HQL语句
     * @param 参数值
     * @return 实体对象集合
     * @throws EXCEPTION
     */
    public List<T> findByNamedQuery(String queryName, Object value) {
        List<T> lst = this.getHibernateTemplate().findByNamedQuery(queryName, value);
        return lst;
    }

    /**
     * 使用带参数的命名HQL语句检索数据
     * 
     * @param 命名HQL语句
     * @param 参数值数组
     * @return 实体对象集合
     * @throws EXCEPTION
     */
    public List<T> findByNamedQuery(String queryName, Object[] values) {
        List<T> lst = this.getHibernateTemplate().findByNamedQuery(queryName, values);
        return lst;
    }

    /**
     * 获取实体信息
     * 
     * @param ID
     * @return 实体类
     * @throws EXCEPTION
     */
    public T get(ID id) {
        T t = (T) this.getHibernateTemplate().get(getEntityClass(), id);
        return t;
    }

    /**
     * 使用条件和排序查询对象获取单个数据
     * 
     * @param 条件和排序查询对象
     * @return 实体对象
     * @throws EXCEPTION
     */
    public T get(SearchBean params) {

        Session session = this.getSession();

        DetachedCriteria detachedCriteria = null;

        Criteria criteria = null;

        if (params == null) {
            params = new SearchBean();
        }

        // 离线查询对象
        detachedCriteria = params.getDetachedCriteria();

        // 如果离线查询对象为非空，则使用离线查询
        if (detachedCriteria != null) {
            // 将离线查询对象绑定到当前Session
            criteria = detachedCriteria.getExecutableCriteria(session);
        } else {
            criteria = session.createCriteria(getEntityClass());

            // 处理查询条件集合
            CriteriaUtil.processParams(criteria, params.getConditions());

            // 处理排序集合
            CriteriaUtil.processOrders(criteria, params.getOrders());

            // 设置缓存
            criteria.setCacheable(params.isCacheAble());

            if (params.isCacheAble()) {
                // 设置缓存类型
                criteria.setCacheMode(params.getCacheMode());
            }

            if (params.getCacheRegion() != null) {
                // 设置缓存范围
                criteria.setCacheRegion(params.getCacheRegion());
            }

            // 设置锁模式
            criteria.setLockMode(params.getLockMode());
            // 设置刷新模式
            criteria.setFlushMode(params.getFlushMode());
            // 设置总数据
            criteria.setMaxResults(1);
        }

        // 设置查询结果
        T result = (T) criteria.uniqueResult();

        return result;
    }

    /**
     * 获取全部数据
     * 
     * @return 实体对象集合
     * @throws EXCEPTION
     */
    public List<T> list() {
        List<T> lst = this.getHibernateTemplate().loadAll(getEntityClass());
        return lst;
    }

    /**
     * 加载实体信息
     * 
     * @param ID
     * @return 实体类
     * @throws EXCEPTION
     */
    public T load(ID id) {
        T t = (T) this.getHibernateTemplate().load(getEntityClass(), id);
        return t;
    }

    /**
     * 刷新实体数据
     * 
     * @param 实体对象
     * @throws EXCEPTION
     */
    public void refresh(T t) {
        this.getHibernateTemplate().refresh(t);

    }

    /**
     * 刷新实体数据并加锁
     * 
     * @param 实体对象
     * @param 锁类型
     * @throws EXCEPTION
     */
    public void refresh(T t, LockMode lockMode) {
        this.getHibernateTemplate().refresh(t, lockMode);

    }

    /**
     * 保存实体对象
     * 
     * @param 实体对象
     * @return 主键ID
     * @throws EXCEPTION
     */
    @Transactional
    public ID save(T t) {
        ID id = (ID) this.getHibernateTemplate().save(t);
        return id;
    }

    public void SaveList(T[] listT) {
        Session se = this.getSession();
        Transaction tra = null;
        try {
            tra = se.beginTransaction();
            for (int i = 0; i < listT.length; i++) {
                T t = listT[i];
                if (!BaseUtil.isEmpty(t)) {
                    se.save(t);
                }
                // if (i % 10 == 0) {
                // se.flush();
                // se.clear();
                // }
            }
            tra.commit();
        } catch (Exception ex) {
            ex.printStackTrace();
            try {
                if (tra != null) tra.rollback();
            } catch (HibernateException e) {}

        }
    }

    /**
     * 保存或更新实体对象
     * 
     * @param 实体对象
     * @throws EXCEPTION
     */
    public void saveOrUpdate(T t) {
        this.getHibernateTemplate().saveOrUpdate(t);
    }

    /**
     * 保存或更新实体对象集合
     * 
     * @param 实体对象集合
     * @throws EXCEPTION
     */
    public void saveOrUpdateAll(Collection<T> entities) {
        this.getHibernateTemplate().saveOrUpdateAll(entities);
        this.getHibernateTemplate().flush();
        this.getSession().flush();
        this.getSession().clear();
    }

    /**
     * 分页查询
     * 
     * @param 分页实体类
     * @throw Exception
     */
    public void searchByPagination(PageBean pageBean) {
        Session session = super.getSession();
        // 离线查询对象
        DetachedCriteria detachedCriteria = pageBean.getParams().getDetachedCriteria();
        Criteria criteria = null;

        if (detachedCriteria != null) {
            // 将离线查询对象绑定到当前Session
            criteria = detachedCriteria.getExecutableCriteria(session);
        } else {
            criteria = session.createCriteria(getEntityClass());

            SearchBean params = pageBean.getParams();

            // 处理查询条件集合
            CriteriaUtil.processParams(criteria, params.getConditions());

            // 获取数据总数
            int totalData = (Integer) criteria.setProjection(Projections.rowCount()).uniqueResult();

            criteria.setProjection(null);

            // 处理排序集合
            CriteriaUtil.processOrders(criteria, params.getOrders());

            // 设置每页最大数据
            criteria.setMaxResults(pageBean.getPageSize());
            // 设置起始索引
            criteria.setFirstResult(pageBean.getStartIndex());
            // 设置缓存
            criteria.setCacheable(params.isCacheAble());

            if (params.isCacheAble()) {
                // 设置缓存类型
                criteria.setCacheMode(params.getCacheMode());
            }

            if (params.getCacheRegion() != null) {
                // 设置缓存范围
                criteria.setCacheRegion(params.getCacheRegion());
            }

            // 设置锁模式
            criteria.setLockMode(params.getLockMode());
            // 设置刷新模式
            criteria.setFlushMode(params.getFlushMode());
            // 设置总数据
            pageBean.setTotalData(totalData);
        }
        // 设置查询结果
        pageBean.setResults(criteria.list());
        releaseSession(session);

    }

    /**
     * 更新实体对象集合
     * 
     * @param 实体对象集合
     * @throws EXCEPTION
     */
    public void update(Collection<T> entities) {
        for (T t : entities) {
            this.update(t);
        }
    }

    /**
     * 更新实体对象
     * 
     * @param 实体对象
     * @throws EXCEPTION
     */
    @Transactional
    public void update(T t) {
        try {
            // this.getSession().setFlushMode(FlushMode.COMMIT);
            this.getHibernateTemplate().update(t);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 更新实体对象并加锁
     * 
     * @param 实体对象
     * @param 锁类型
     * @throws EXCEPTION
     */
    public void update(T t, LockMode lockMode) {
        this.getHibernateTemplate().update(t, lockMode);

    }

    /**
     * 获取属于该父ID值的新的ID值，该ID值必须为String类型 <br>
     * 该算法适用于<br>
     * -0<br>
     * |-01<br>
     * |--0101<br>
     * |--0102<br>
     * |-02<br>
     * |--0201<br>
     * 此种树状类型的ID值 <br>
     * <br>
     * <b>可在Dao类中重写此方法，将列名值固定，只传入parentID一个值</b>
     * 
     * @param ID列名
     * @param 父ID列名
     * @param 父ID值
     * @return 返回新的ID值
     * @throws EXCEPTION
     */
    public String getNewID(String colID, String colParentID, String parentID) {
        if (parentID == null) {
            return null;
        }
        Criteria criteria = null;
        Session session = getSession();
        // 获取ID列的最大值
        String id = null;
        try {
            criteria = session.createCriteria(getEntityClass());
            // 查询父ID为parentID的最大ID
            criteria.add(Restrictions.eq(colParentID, parentID));
            id = criteria.setProjection(Projections.max(colID)).uniqueResult().toString();
        } catch (NullPointerException e) {
            criteria = session.createCriteria(getEntityClass());
            // 查询ID为parentID的数据是否存在
            criteria.add(Restrictions.eq(colID, parentID));
            int resultCount = (Integer) criteria.setProjection(Projections.count(colID)).uniqueResult();
            // 如果该ID不存在，父ID为0时的情况，子ID为01
            // 如果该ID存在，该ID仅存在于ID列，子ID为XX01
            // 如果该ID存在，该ID为0，子ID为01

            if (parentID.length() < 2) {
                id = resultCount == 0 ? parentID : parentID.concat("0");
            } else {
                id = resultCount == 0 ? parentID : parentID.concat("00");
            }
        }
        // 最后2位
        String last2Bits = null;
        // 前N位，如果id的长度大于等于2， 则获取前N-2位，否则前N位位空
        String firstBits = id.length() >= 2 ? id.substring(0, id.length() - 2) : "";
        // 如果最大id长度大于2， 则获取该id的最后2位，如果id小于2位，则最后2位为id原来的值
        last2Bits = id.length() > 2 ? id.substring(id.length() - 2, id.length()) : id;
        // 计数值，最后2位转化位整形的值，并在原有基础上 +1
        int count = Integer.valueOf(last2Bits) + 1;
        // 新的2位：如果计数值小于9, 则在其前补0
        String new2Bit = count <= 9 ? "0".concat(count + "") : count + "";
        // 拼凑新的ID值
        String newId = firstBits.concat(new2Bit);
        // 返回新的ID值
        return newId;
    }

    @Override
    public Object[] findAggregation(SearchBean params, String[][] aggparams) {
        if (aggparams == null || aggparams.length == 0) {
            return null;
        }
        Session session = this.getSession();

        Criteria criteria = null;

        if (params == null) {
            params = new SearchBean();
        }
        criteria = session.createCriteria(getEntityClass());
        // 设置查询字段
        ProjectionList proList = Projections.projectionList();
        for (int i = 0; i < aggparams.length; i++) {
            if (aggparams[i].length != 2) {// 参数错误
                continue;
            }
            if (aggparams[i][0].equalsIgnoreCase("sum")) {
                proList.add(Projections.sum(aggparams[i][1]));
            } else if (aggparams[i][0].equalsIgnoreCase("avg")) {
                proList.add(Projections.avg(aggparams[i][1]));
            } else if (aggparams[i][0].equalsIgnoreCase("max")) {
                proList.add(Projections.max(aggparams[i][1]));
            } else if (aggparams[i][0].equalsIgnoreCase("min")) {
                proList.add(Projections.min(aggparams[i][1]));
            }
        }
        criteria.setProjection(proList);
        // 查询条件
        CriteriaUtil.processParams(criteria, params.getConditions());

        criteria.setCacheable(params.isCacheAble());

        if (params.isCacheAble()) {
            criteria.setCacheMode(params.getCacheMode());
        }

        if (params.getCacheRegion() != null) {
            criteria.setCacheRegion(params.getCacheRegion());
        }

        // 设置锁模式
        // criteria.setLockMode(params.getLockMode());
        // 设置刷新模式
        criteria.setFlushMode(params.getFlushMode());

        // 设置查询结果
        List<?> results = criteria.list();
        if (results == null) {
            return null;
        }
        return (Object[]) results.get(0);
    }

    @Override
    public List<Object[]> findPacketStatistics(SearchBean params, String[][] aggparams, String[] psParams) {
        if (aggparams == null || aggparams.length == 0 || psParams == null || psParams.length == 0) {
            return null;
        }
        Session session = this.getSession();

        Criteria criteria = null;

        if (params == null) {
            params = new SearchBean();
        }
        criteria = session.createCriteria(getEntityClass());
        // 设置查询字段
        ProjectionList proList = Projections.projectionList();
        for (int i = 0; i < psParams.length; i++) {
            proList.add(Projections.groupProperty(psParams[i]));
        }
        for (int i = 0; i < aggparams.length; i++) {
            if (aggparams[i].length != 2) {// 参数错误
                continue;
            }
            if (aggparams[i][0].equalsIgnoreCase("sum")) {
                proList.add(Projections.sum(aggparams[i][1]));
            } else if (aggparams[i][0].equalsIgnoreCase("avg")) {
                proList.add(Projections.avg(aggparams[i][1]));
            } else if (aggparams[i][0].equalsIgnoreCase("max")) {
                proList.add(Projections.max(aggparams[i][1]));
            } else if (aggparams[i][0].equalsIgnoreCase("min")) {
                proList.add(Projections.min(aggparams[i][1]));
            } else if (aggparams[i][0].equalsIgnoreCase("count")) {
                proList.add(Projections.rowCount());
            }
        }
        criteria.setProjection(proList);
        // 查询条件
        CriteriaUtil.processParams(criteria, params.getConditions());

        criteria.setCacheable(params.isCacheAble());

        if (params.isCacheAble()) {
            criteria.setCacheMode(params.getCacheMode());
        }

        if (params.getCacheRegion() != null) {
            criteria.setCacheRegion(params.getCacheRegion());
        }

        // 设置锁模式
        // criteria.setLockMode(params.getLockMode());
        // 设置刷新模式
        criteria.setFlushMode(params.getFlushMode());

        // 设置查询结果
        List<?> results = criteria.list();
        if (results == null) {
            return null;
        }
        return (List<Object[]>) results;
    }

    // public void batchSave(T t){
    // Session session=this.getSession();
    // Connection conn = session.connection();
    // pStmt = conn.prepareStatement(sql);
    //
    // }
}
